package dialog;

import bean.Kreditgeber;
import bean.Kunde;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

public class Main {

  private List<Kunde> kunden = new ArrayList<>();
  private EinUndAusgabe io = new EinUndAusgabe();
  // -------------------------------- >>
  private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
  // -------------------------------- <<

  public void dialog() {
    int eingabe = -1;
    while (eingabe != 0) {
      System.out.println("Was wollen Sie\n"
              + " (0) Programm beenden\n"
              + " (1) Kunden ergänzen");
      if (kunden.size() > 0) {
        System.out.println(" (2) Kredit für Kunden ergänzen");
      }
      System.out.println(" (3) Gesamtübersicht");
      eingabe = io.leseInteger();
      switch (eingabe) {
        case 1:
          kundeErgaenzen();
          break;
        case 2:
          if (kunden.size() > 0) {
            kreditFuerKundeErgaenzen();
          }
          break;
        case 3:
          uebersicht();
          break;
      }
    }
  }

  public void kundeErgaenzen() {
    Kunde k = new Kunde();
    boolean ok = false;
    while (!ok) {
        System.out.print("Name: ");
        
        // -------------------------------- >>
        // prüfe: Name des Kunden hat mindestens ein Zeichen
        k.setName(io.leseString());
        Set<ConstraintViolation<Kunde>> nameViolation = validator.validateProperty( k, "name" );
        if ( nameViolation.isEmpty() ){
            ok = true;
        }
        else{
            System.out.println( ":: " + new ArrayList<>(nameViolation).get( 0 ).getMessage() );
        }
        // -------------------------------- <<
    }
    
    
    ok = false;
    while (!ok) {
        System.out.print("Kreditrahmen: ");
        
        // -------------------------------- >>
        // prüfe: Maximaler Kreditrahmen nicht negativ
        BigInteger value;
        try{
            value = new BigInteger(io.leseString());
        }
        catch(Exception e){
            value = new BigInteger( "-1" );
        }
        k.setMaxKredit( value );
        Set<ConstraintViolation<Kunde>> nameViolation = validator.validateProperty( k, "maxKredit" );
        if ( nameViolation.isEmpty() ){
            ok = true;
        }
        else{
            System.out.println( ":: " + new ArrayList<>(nameViolation).get( 0 ).getMessage() );
        }
        // -------------------------------- <<
    }
    kunden.add(k);
  }

  
  
  private Kunde kundeWaehlen() {
    for (int i = 0; i < kunden.size(); i++) {
      // -------------------------------- >>
      // gebe alle Kunden aus
      System.out.println( i+1 + " " + kunden.get(i).getName() );
      // -------------------------------- <<
    }
    int eingabe = -1;
    while (eingabe < 1 || eingabe > kunden.size()) {
      System.out.print("Welcher Kunde: ");
      eingabe = io.leseInteger();
    }
    return kunden.get(eingabe - 1);
  }

  private void kreditFuerKundeErgaenzen() {
    Kunde k = kundeWaehlen();
    Kreditgeber kg = new Kreditgeber();
    boolean ok = false;
    while (!ok) {
      System.out.print("Name Kreditgeber: ");
      // -------------------------------- >>
      // prüfe: Name des Kreditgebers hat genau drei Zeichen
      kg.setName( io.leseString() );
      Set<ConstraintViolation<Kreditgeber>> nameViolation = validator.validateProperty( kg, "name" );
      if ( nameViolation.isEmpty() ){
        ok = true;
      }
      else{
        System.out.println( ":: " + new ArrayList<>(nameViolation).get( 0 ).getMessage() );
      }
      // -------------------------------- <<
    }
    
    ok = false;
    while (!ok) {
      System.out.print("Kreditsumme: ");
      // -------------------------------- >>
      // prüfe: Kreditsumme muss positiv sein
      BigInteger value;
      try{
          value = new BigInteger(io.leseString());
      }
      catch(Exception e){
          value = new BigInteger( "-1" );
      }
      kg.setSumme( value );
      Set<ConstraintViolation<Kreditgeber>> summeViolation = validator.validateProperty( kg, "summe" );
      if ( summeViolation.isEmpty() ){
        ok = true;
      }
      else{
        System.out.println( ":: " + new ArrayList<>(summeViolation).get( 0 ).getMessage() );
      }
      // -------------------------------- <<
    }
    // -------------------------------- >>
    // prüfe: Es gibt maximal vier Kredite
    // prüfe: Es gibt keine zwei Kredite vom gleichen Kreditgeber
    k.setKredit(kg);
    
    Set<ConstraintViolation<Kunde>> krediteViolation = validator.validateProperty( k, "kredite" );
    if ( !krediteViolation.isEmpty() ){
      for ( ConstraintViolation<Kunde> violation : krediteViolation ){
          System.out.println( ":: " + violation.getMessage() );
          k.removeLastKredit();
      }
    }
    
    // prüfe: Die Summe der Kredite überschreitet nicht den maximalen Kreditrahmen
    Set<ConstraintViolation<Kunde>> summeViolations = validator.validate( k, Annotations.Kredit.class );
    if ( summeViolations.isEmpty() ){
      ok = true;
    }
    else{
      for ( ConstraintViolation<Kunde> violation : summeViolations ){
          System.out.println( violation.getPropertyPath() + " " + violation.getMessage() );
      }
    }
    // -------------------------------- <<
  }

  private void uebersicht() {
    for (Kunde k : kunden) {
      System.out.println(k);
    }
  }

  public static void main(String[] args) {
    new Main().dialog();
  }
}
